

local modid = 'webber_the_trainer' -- 唯一识别id
local container_prefabid = 'webbert_pack' -- 需要设置翻页的容器的prefabid
local row = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_pack.ui.row_singlepage -- 每行的格子数
local col = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_pack.ui.col_singlepage -- 每列的格子数
local maxpage = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_pack.ui.page -- 最大页数
-----------
local config_prefix = modid
local config_pagebtns =  config_prefix..'_pagebtns'
local config_toright = config_prefix..'_toright'
local config_toleft = config_prefix..'_toleft'
local config_pagehint = config_prefix..'_pagehint'

local Image = require "widgets/image"
local ImageButton = require "widgets/imagebutton"
local Text = require "widgets/text"
local UIAnim = require "widgets/uianim"
local TextEdit = require "widgets/textedit"

local function checkTarContainer(m,id)
    return m.container and m.container.prefab == id and m.container or nil
end

AddClassPostConstruct('widgets/containerwidget',function (self, ...)
    local old_Open = self.Open
    function self:Open(container, doer, ...)
        if old_Open ~= nil then
            old_Open(self, container, doer, ...)
        end
        ---@type ent|nil
        local box = checkTarContainer(self,container_prefabid)
        if box then
            -- self.bganim:SetScale(1.7,1.85,1)
            self.bganim:SetScale(1.7,2.2,1)
            if self[config_pagebtns] == nil then
                self[config_pagebtns] = true
                box.cur_page = box.cur_page or 1
                local slots_per_page = row * col
                for i = 1, row*col*maxpage do
                    if math.ceil(i / slots_per_page) == box.cur_page then
                        self.inv[i]:Show()
                    else
                        self.inv[i]:Hide()
                    end
                end

                ---@type widget_imagebutton
                local sbnh

                local r_x,y = 70,-200-100
                local btn_scale = .6
                self[config_pagehint] = self:AddChild(Text(NUMBERFONT, 35, box.cur_page .. '/' .. maxpage))
                self[config_pagehint]:SetPosition(0,y)

                self[config_toright] = self:AddChild(ImageButton('images/global_redux.xml','arrow2_right.tex','arrow2_right.tex','arrow2_right.tex','arrow2_right.tex','arrow2_right.tex'))
                self[config_toright]:SetPosition(r_x,y)
                self[config_toright]:SetScale(btn_scale,btn_scale)
                self[config_toright]:SetOnClick(function ()
                    box.cur_page = math.clamp(box.cur_page+1,1,maxpage)
                    for i = 1, row*col*maxpage do
                        if math.ceil(i / slots_per_page) == box.cur_page then
                            self.inv[i]:Show()
                        else
                            self.inv[i]:Hide()
                        end
                    end
                    self[config_pagehint]:SetString(box.cur_page .. '/' .. maxpage)
                    SendModRPCToServer(GetModRPC(modid,modid..'container_switch_page'),box.cur_page,box)
                end)

                ---@type widget_uianim
                self.title_frame = self:AddChild(UIAnim())
                self.title_frame:GetAnimState():SetBuild("fx_goldenframeflow")
                self.title_frame:GetAnimState():SetBank("fx_goldenframeflow")
                self.title_frame:GetAnimState():PlayAnimation("idle", true)
                self.title_frame:SetPosition(0,310)
                self.title_frame:SetScale(1.5,1.5,1.5)

                self.title_text = self:AddChild(Text(TITLEFONT, 40, STRINGS.MOD_WEBBER_THE_TRAINER.UI.webbert_sack.title))
                self.title_text:SetPosition(0,310)

                self[config_toleft] = self:AddChild(ImageButton('images/global_redux.xml','arrow2_left.tex','arrow2_left.tex','arrow2_left.tex','arrow2_left.tex','arrow2_left.tex'))
                self[config_toleft]:SetPosition(-r_x,y)
                self[config_toleft]:SetScale(btn_scale,btn_scale)
                self[config_toleft]:SetOnClick(function ()
                    box.cur_page = math.clamp(box.cur_page-1,1,maxpage)
                    for i = 1, row*col*maxpage do
                        if math.ceil(i / slots_per_page) == box.cur_page then
                            self.inv[i]:Show()
                        else
                            self.inv[i]:Hide()
                        end
                    end
                    self[config_pagehint]:SetString(box.cur_page .. '/' .. maxpage)
                    SendModRPCToServer(GetModRPC(modid,modid..'container_switch_page'),box.cur_page,box)
                end)
                --------------------
                self.edit_text_bg = self:AddChild( Image() )
                self.edit_text_bg:SetTexture( "images/global_redux.xml", "textbox3_gold_normal.tex" )
                self.edit_text_bg:SetPosition( -20, 220 )
                self.edit_text_bg:ScaleToSize( 340, 40 )

                ---@type widget_textedit
                self.edit_text = self:AddChild( TextEdit( NEWFONT, 25, "" ) )
                self.edit_text:SetPosition( -10, 220 )
                self.edit_text:SetRegionSize( 300, 40 )
                self.edit_text:SetHAlign(ANCHOR_LEFT)
                self.edit_text:SetOnGainFocus(function ()
                    ThePlayer.components.playercontroller:Enable(false)
                    ThePlayer.is_editing = true
                end)
                self.edit_text:SetOnLoseFocus(function()
                    ThePlayer.components.playercontroller:Enable(true)
                    ThePlayer.is_editing = false
                end)
                local old_OnTextInput = self.edit_text.OnTextInput
                local inv = self.inv
                function self.edit_text:OnTextInput(text,...)
                    local res = old_OnTextInput ~= nil and {old_OnTextInput(self,text,...)} or {}
                    local key = self:GetLineEditString()
                    if key and key == '' then
                        key = nil
                    end
                    if key == nil then
                        for i = 1, row*col*maxpage do
                            if math.ceil(i / slots_per_page) == box.cur_page then
                                inv[i]:Show()
                            end
                        end
                    else
                        for i = 1, row*col*maxpage do
                            if math.ceil(i / slots_per_page) == box.cur_page then
                                local hide = true
                                local itm = box.replica.container:GetItemInSlot(i)
                                if key and itm and itm.prefab and string.find(itm.prefab,key) then
                                    hide = false
                                end
                                if hide then
                                    inv[i]:Hide()
                                else
                                    inv[i]:Show()
                                end
                            end
                        end
                    end
                    return unpack(res)
                end

            end
        end
    end
end)

AddModRPCHandler(modid,modid..'container_switch_page',function (player, page,box)
    if box and page then
        box.cur_page = page
    end
end)

AddClassPostConstruct('components/container_replica',
---comment
---@param self replica_container
---@param ... unknown
function (self, ...)
    local old_GetSpecificSlotForItem = self.GetSpecificSlotForItem
    function self:GetSpecificSlotForItem(item,...)
        if item ~= nil and self.inst.prefab == container_prefabid and self.usespecificslotsforitems then
            local free_slot = nil
            for i = 1, self:GetNumSlots() do
                if math.ceil(i / (row*col)) == (self.inst.cur_page or 1) then
                    local item_in_slot = self:GetItemInSlot(i)
                    if item_in_slot ~= nil and item_in_slot.prefab == item.prefab and item_in_slot.replica.stackable and not item_in_slot.replica.stackable:IsFull() then
                        return i
                    end
                    if item_in_slot == nil then
                        if free_slot == nil then
                            free_slot = i
                        elseif free_slot > i then
                            free_slot = i
                        end
                    end
                end
            end
            return free_slot
        end
        return old_GetSpecificSlotForItem ~= nil and old_GetSpecificSlotForItem(self, item,...) or nil
    end
end)

AddComponentPostInit('container',
---@param self component_container
function (self)
    local old_GetSpecificSlotForItem = self.GetSpecificSlotForItem
    function self:GetSpecificSlotForItem(item,...)
        if item ~= nil and self.inst.prefab == container_prefabid and self.usespecificslotsforitems then
            local free_slot = nil
            for i = 1, self:GetNumSlots() do
                if math.ceil(i / (row*col)) == (self.inst.cur_page or 1) then
                    local item_in_slot = self:GetItemInSlot(i)
                    if item_in_slot ~= nil and item_in_slot.prefab == item.prefab and item_in_slot.components.stackable and not item_in_slot.components.stackable:IsFull() then
                        return i
                    end
                    if item_in_slot == nil then
                        if free_slot == nil then
                            free_slot = i
                        elseif free_slot > i then
                            free_slot = i
                        end
                    end
                end
            end
            return free_slot
        end
        return old_GetSpecificSlotForItem ~= nil and old_GetSpecificSlotForItem(self,item,...) or nil
    end
end)